home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
glass
/
glass.lha
/
GLASS
/
uflat2
/
uflat2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-18
|
32KB
|
1,186 lines
/*
File: uflat2.c
*/
#include <strings.h>
#include <stdio.h>
#include <tmc.h>
#include <cvr.h>
#include "uflat2const.h"
#include "tmcode.h"
#include "utils.h"
/* command line flags */
static int showorig = TRUE;
static int symtabtr = FALSE;
static int stat = FALSE;
static int orignames = FALSE;
/* common variables */
#define infile stdin
#define outfile stdout
FILE *tracestream = stderr;
/* fields of definition to be monitored */
typ intyp, outtyp;
formcon deffc, newfc;
val defval;
def_list fcdefs;
typ *ctypes;
int firstsrcnr;
int nrofinputs;
/* definitions to be written to disk */
def_list newdefs;
/* names of procs and locals */
#define proclowend 100
int procnr = proclowend;
/*
Table of debugging flags plus associated information.
Table is ended by an entry with flagchar '\0'
*/
static dbflag flagtab[] =
{{ 's', &stat, "statistics" },
{ 't', &symtabtr, "symbol table tracing" },
{ '\0', (int *)0, "" },
};
#define streq(s1,s2) (strcmp ((s1),(s2)) == 0)
/*
Die with errormessage
*/
static void Die (s)
char *s;
{ fprintf (stderr, "%s\n", s);
exit (1);
};
/*
Name from symbol.
Because the macroexpander adds _<number> to every symbol
we must remove that suffix when recognizing atoms or source symbols
*/
static char* name_from_symbol (s)
symbol s;
{ char Buf[80];
char *name = symbolstr (s);
int ix;
for (ix = 0; ix < strlen (name) && !(name[ix] == '_'); ix++)
Buf [ix] = name [ix];
Buf [ix] ='\0';
return (new_string (Buf));
};
/*
Create an unique symbol
*/
static int uniquenr = 0;
static symbol unique_name ()
{ char Buf[20];
symbol new;
sprintf (Buf, "l_'_%d", uniquenr);
new = addsymbol (new_string (Buf));
setprior (new, uniquenr);
uniquenr++;
return (new);
};
/*
Give the formal connection parameters of a def
a procedure nr. We will need it to deduce types.
*/
static void prepare1_formcon (fc)
formcon fc;
{ switch (fc -> tag)
{ case TAGFCSym:
{ setprior (fc -> FCSym.sym, procnr);
procnr++;
};
break;
case TAGFCList:
{ register ix;
formcon_list fcl = fc -> FCList.l;
for (ix = 0; ix < fcl -> sz; ix++)
prepare1_formcon (fcl -> arr[ix]);
};
break;
default: badtag (fc -> tag);
};
};
/*
Find the type belonging to each 'fc'.
Do also some consistency checks.
*/
static void prepare2_formcon (fc,t)
formcon fc;
typ t;
{ switch (fc -> tag)
{ case TAGFCSym:
{ symbol sy = fc -> FCSym.sym;
int nr = getprior (sy);
ctypes [nr - proclowend] = rdup_typ (t);
};
break;
case TAGFCList:
{ formcon_list fcl = fc -> FCList.l;
register int ix;
typ_list tl;
if (t -> tag != TAGTypProd)
Die ("type should be product type");
tl = t -> TypProd.ptypes;
if (fcl -> sz != tl -> sz)
Die ("formcon list and type list should have equal size");
for (ix=0; ix < fcl -> sz; ix++)
prepare2_formcon (fcl -> arr[ix], tl -> arr[ix]);
};
break;
default: badtag (fc -> tag);
};
};
/*
Prepare formal parameters of the definition
*/
static void prepare_formcon (fc, t)
formcon fc;
typ t;
{ int ix;
firstsrcnr = procnr;
prepare1_formcon (fc);
nrofinputs = procnr - firstsrcnr;
ctypes = (typ*) ckcalloc (procnr+1, sizeof (typ));
for (ix=0; ix < procnr; ix++) ctypes[ix] = typNIL;
prepare2_formcon (fc, t);
};
/* Given a symbol 's', search the context for a definition with
* that name, and return a pointer to it.
*/
static ctx_list context;
static int symbol_occurs_in (s, v)
symbol s;
val v;
{ switch (v -> tag)
{ case TAGVSym: return (v -> VSym.sym == s);
case TAGVList:
{ val_list vl = v -> VList.l;
register int ix;
for (ix=0; ix < vl -> sz; ix++)
if (symbol_occurs_in (s, vl -> arr[ix])) return (1);
return (0);
};
default: badtag (v -> tag);
};
};
static def find_def (s)
symbol s;
{ register unsigned int cix;
register unsigned int dix;
for (cix = 0; cix < context -> sz; cix++)
{ register def_list l = context -> arr[cix] -> defs;
for (dix = 0; dix < l -> sz; dix++)
{ register def d = l -> arr[dix];
switch (d -> tag)
{ case TAGDefAtom:
if (d -> DefAtom.atnm == s) return (d);
break;
case TAGDefBasetype:
if (d -> DefBasetype.basename == s) return (d);
break;
case TAGDefVal:
if (d -> DefVal.valnm == s) return (d);
break;
case TAGDefTyp:
if (d -> DefTyp.typnm == s) return (d);
break;
case TAGDefCon:
Die ("DefCon should have been removed");
case TAGDefConTr:
if (symbol_occurs_in (s, d -> DefConTr.lhs))
return (d);
break;
default:
badtag (d -> tag);
};
};
}
return (defNIL);
};
/* Copy all global basetype and atom definitions */
static copy_basenamedefs (new, old)
def_list new, old;
{ register int ix;
register def d;
for (ix = 0; ix < old -> sz; ix++)
{ d = old -> arr[ix];
switch (d -> tag)
{ case TAGDefAtom:
app_def_list (new, rdup_def (d));
break;
case TAGDefBasetype:
app_def_list (new, rdup_def (d));
break;
case TAGDefVal:
break;
case TAGDefCon:
case TAGDefTyp:
default:
badtag (d -> tag);
break;
};
};
};
/* Print usage of this program */
static void usage (f)
FILE *f;
{ fprintf (f, "Usage: uflat2 [-n] [-h] [-d<debugging flags>]\n");
helpdbflags (f, flagtab);
};
/* scan arguments and options */
static void scanargs (argc, argv)
int argc;
char *argv[];
{ int op;
argv++;
argc--;
while (argc>0)
{ if (argv[0][0] != '-')
{ fprintf (stderr, "too many arguments\n");
usage (stderr);
exit (1);
};
op = argv[0][1];
switch (op)
{ case 'd': setdbflags (&argv[0][2], flagtab, TRUE);
break;
case 'h':
case 'H': usage (stdout);
exit (0);
case 'o': showorig = FALSE;
break;
case 'n': orignames = TRUE;
break;
default: usage (stderr);
exit (1);
};
argc--;
argv++;
};
};
static def find_thedef (dl)
def_list dl;
{ register int ix;
register def d;
register def mdef = defNIL;
for (ix = 0; ix < dl -> sz; ix++)
{ d = dl -> arr[ix];
if (d -> tag == TAGDefVal)
{ if (mdef == defNIL)
{ mdef = d;
}
else Die ("More than one codible definition found");
};
};
if (mdef == defNIL) Die ("No codible definition found");
return (mdef);
};
/*
Prepare the value to be coded:
Record procedure nrs for right hand sides of local definitions:
Introduce also local definitions for atoms with internal feedback
like the jkff and tff.
*/
static val prepare_val (v)
val v;
{ switch (v -> tag)
{ case TAGVSym: return (rdup_val (v));
case TAGVWhere:
{ register ix;
def_list ndl = new_def_list ();
def_list dl = v -> VWhere.wdefs;
room_def_list (ndl, dl -> sz);
ndl -> sz = dl -> sz;
for (ix = 0; ix < dl -> sz; ix++)
{ register def d = dl -> arr [ix];
val newrhs;
if (d -> tag != TAGDefCon)
Die ("Only local connections allowed");
newrhs = prepare_val (d -> DefCon.conas);
ndl -> arr [ix] =
new_DefConTr (rdup_orig (d -> DefCon.conorig),
rdup_val (d -> DefCon.defcon),
newrhs, procnr);
procnr++;
};
return (new_VWhere (ndl, prepare_val (v -> VWhere.wval)));
};
case TAGVList:
{ register ix;
val_list vl = v -> VList.l;
val_list nvl = new_val_list ();
room_val_list (nvl, vl -> sz);
nvl -> sz = vl -> sz;
for (ix=0; ix < vl -> sz; ix++)
nvl -> arr [ix] = prepare_val (vl -> arr[ix]);
return (new_VList (nvl));
};
case TAGVAtom:
{ return (new_VAtom (rdup_orig (v -> VAtom.atorig),
rdup_symbol (v -> VAtom.atnm),
rdup_parval_list (v -> VAtom.atvpar),
prepare_val (v -> VAtom.atcpar)));
};
case TAGVLambda:
case TAGVSigma:
case TAGVApply:
case TAGVAppset:
case TAGVSyn:
Die ("Only wheres, atom applications, lists and symbols are allowed");
default:
badtag (v -> tag);
};
};
/*
prepare types
*/
static typ partial_build_typ (v, s, t)
val v;
symbol s;
typ t;
{ switch (v -> tag)
{ case TAGVSym:
{ if (v -> VSym.sym == s) return (rdup_typ (t));
return (typNIL);
};
case TAGVList:
{ register int ix;
val_list vl = v -> VList.l;
typ_list tl = new_typ_list ();
room_typ_list (tl, vl -> sz);
tl -> sz = vl -> sz;
for (ix=0; ix < vl -> sz; ix++)
tl -> arr[ix] = partial_build_typ (vl -> arr[ix], s, t);
return (new_TypProd (tl));
};
default: badtag (v -> tag);
};
};
/*
Unify types
*/
static typ unify_types (t1,t2)
typ t1,t2;
{ if (t1 == typNIL) return (rdup_typ (t2));
if (t2 == typNIL) return (rdup_typ (t1));
if (t1 -> tag != t2 -> tag) Die ("Can not unify types");
switch (t1 -> tag)
{ case TAGTypBase: return (rdup_typ (t1));
case TAGTypProd:
{ typ_list t1l = t1 -> TypProd.ptypes;
typ_list t2l = t2 -> TypProd.ptypes;
typ_list ntl = new_typ_list ();
register int ix;
if (t1l -> sz != t2l -> sz) Die ("Can not unify types");
room_typ_list (ntl, t1l -> sz);
ntl -> sz = t1l -> sz;
for (ix=0; ix < t1l -> sz; ix++)
ntl -> arr[ix] = unify_types (t1l -> arr[ix],
t2l -> arr[ix]);
return (new_TypProd (ntl));
};
default: badtag (t1 -> tag);
};
};
static void update_type_in_def (d, t)
def d;
typ t;
{ int nr = d -> DefConTr.nr - proclowend;
typ newtyp = unify_types (ctypes [nr], t);
rfre_typ (ctypes [nr]);
ctypes [nr] = newtyp;
};
static typ deduce_types_in_val ();
static void deduce_types_in_def (d)
def d;
{ int nr = d -> DefConTr.nr - proclowend;
typ t = deduce_types_in_val (d -> DefConTr.rhs, ctypes [nr]);
update_type_in_def (d,t);
rfre_typ (t);
};
static typ project_type (t, v, s)
typ t;
val v;
symbol s;
{ if (t == typNIL) return (typNIL);
switch (v -> tag)
{ case TAGVSym:
{ if (v -> VSym.sym == s) return (rdup_typ (t));
return (typNIL);
};
case TAGVList:
{ register int ix;
typ rettyp;
typ_list tl = t -> TypProd.ptypes;
val_list vl = v -> VList.l;
for (ix=0; ix < vl -> sz; ix++)
if ((rettyp = project_type (tl -> arr[ix],
vl -> arr[ix], s)) != typNIL)
return (rettyp);
return (typNIL);
};
default: badtag (v -> tag);
};
};
static typ deduce_types_in_val (v,t)
val v;
typ t;
{ switch (v -> tag)
{ case TAGVSym:
{ symbol sy = v -> VSym.sym;
def d;
int nr = getprior (sy);
if (nr >= firstsrcnr)
return (rdup_typ (ctypes [nr - proclowend]));
if ((d = find_def (sy)) == defNIL)
Die ("definition not found");
if (t != typNIL)
{ typ parttyp = partial_build_typ
(d -> DefConTr.lhs, sy, t);
update_type_in_def (d, parttyp);
rfre_typ (parttyp);
};
nr = d -> DefConTr.nr;
return (project_type (ctypes[nr - proclowend],
d -> DefConTr.lhs, sy));
};
case TAGVList:
{ val_list vl = v -> VList.l;
typ_list gtl = typ_listNIL;
int ix;
typ_list ntl = new_typ_list ();
room_typ_list (ntl, vl -> sz);
ntl -> sz = vl -> sz;
if (t != typNIL)
{ if ((t -> tag != TAGTypProd) ||
(t -> TypProd.ptypes -> sz != vl -> sz))
Die ("Mismatch between type and value");
gtl = rdup_typ_list (t -> TypProd.ptypes);
};
for (ix=0; ix < ntl -> sz; ix++)
ntl -> arr[ix] = deduce_types_in_val (vl -> arr[ix],
(t==typNIL)?typNIL:gtl -> arr[ix]);
rfre_typ_list (gtl);
return (new_TypProd (ntl));
};
case TAGVAtom:
{ symbol atnm = v -> VAtom.atnm;
def d = find_def (atnm);
typ dummy = deduce_types_in_val (v -> VAtom.atcpar,
d -> DefAtom.atctyp -> TypUni.uityp);
rfre_typ (dummy);
return (rdup_typ (d -> DefAtom.atctyp -> TypUni.uotyp));
};
case TAGVWhere:
{ typ dummy, rettyp;
typ srctyp = rdup_typ (t); /* t may be overwritten */
def_list dl = v -> VWhere.wdefs;
int ix;
ins_ctx_list (context, 0, new_ctx (rdup_def_list (dl)));
if (t != typNIL)
dummy = deduce_types_in_val (v -> VWhere.wval, srctyp);
for (ix=0; ix < dl -> sz; ix++)
deduce_types_in_def (dl -> arr[ix]);
rettyp = deduce_types_in_val (v -> VWhere.wval, srctyp);
rfre_typ (dummy);
rfre_typ (srctyp);
del_ctx_list (context, 0);
return (rettyp);
};
default: badtag (v -> tag);
};
};
static void deduce_all_where_types ()
{ typ dummy;
context = new_ctx_list ();
ins_ctx_list (context, 0, new_ctx (rdup_def_list (newdefs)));
dummy = deduce_types_in_val (defval, outtyp);
rfre_typ (dummy);
rfre_ctx_list (context);
};
/*
check if the types of all right hand sides are defined
*/
static int fully_defined (t)
typ t;
{ switch (t -> tag)
{ case TAGTypBase: return (1);
case TAGTypProd:
{ typ_list tl = t -> TypProd.ptypes;
register int ix;
for (ix=0; ix < tl -> sz; ix++)
if (!fully_defined (tl -> arr[ix]))
return (0);
return (1);
};
default: badtag (t -> tag);
};
};
static void check_if_all_types_defined ()
{ int ix;
for (ix=0; ix < procnr-proclowend; ix++)
if (!fully_defined (ctypes[ix]))
Die ("Not all types could be found");
};
static void prepare_types ()
{ deduce_all_where_types ();
check_if_all_types_defined ();
};
/*
Now that you know every type, rewrite all symbols,
so that what remains only contains local symbols having
the basetype as type
*/
static formcon unique_formcon_of_type (t)
typ t;
{ switch (t -> tag)
{ case TAGTypBase:
return (new_FCSym (unique_name ()));
case TAGTypProd:
{ register int ix;
typ_list tl = t -> TypProd.ptypes;
formcon_list nfc = new_formcon_list ();
room_formcon_list (nfc, tl -> sz);
nfc -> sz = tl -> sz;
for (ix = 0; ix < tl -> sz; ix++)
nfc -> arr[ix] = unique_formcon_of_type (tl -> arr[ix]);
return (new_FCList (nfc));
};
default: badtag (t -> tag);
};
};
static val formcon_to_val (org, fc)
orig org;
formcon fc;
{ switch (fc -> tag)
{ case TAGFCSym:
return (new_VSym (rdup_orig (org),
rdup_symbol (fc -> FCSym.sym)));
case TAGFCList:
{ register int ix;
formcon_list fcl = fc -> FCList.l;
val_list nvl = new_val_list ();
room_val_list (nvl, fcl -> sz);
nvl -> sz = fcl -> sz;
for (ix = 0; ix < nvl -> sz; ix++)
nvl -> arr [ix] = formcon_to_val (org, fcl -> arr [ix]);
return (new_VList (nvl));
};
default: badtag (fc -> tag);
};
};
static val unique_val_of_type (org, t)
orig org;
typ t;
{ switch (t -> tag)
{ case TAGTypBase:
return (new_VSym (rdup_orig (org), unique_name ()));
case TAGTypProd:
{ register int ix;
typ_list tl = t -> TypProd.ptypes;
val_list nvl = new_val_list ();
room_val_list (nvl, tl -> sz);
nvl -> sz = tl -> sz;
for (ix = 0; ix < tl -> sz; ix++)
nvl -> arr[ix] = unique_val_of_type (org, tl -> arr[ix]);
return (new_VList (nvl));
};
default: badtag (t -> tag);
};
};
static formcon add_to_repls_from_fc (repls, org, fc, fcdefs)
repl_list repls;
orig org;
formcon fc;
def_list fcdefs;
{ switch (fc -> tag)
{ case TAGFCSym:
{ int nr = getprior (fc -> FCSym.sym);
formcon unfc = unique_formcon_of_type
(ctypes [nr - proclowend]);
val unval = formcon_to_val (org, unfc);
app_repl_list (repls, new_repl
(rdup_symbol (fc -> FCSym.sym), unval));
app_def_list (fcdefs, new_DefCon (rdup_orig (org),
rdup_val (unval),
formcon_to_val (org, fc)));
return (unfc);
};
break;
case TAGFCList:
{ register ix;
formcon_list fcl = fc -> FCList.l;
formcon_list nfcl = new_formcon_list ();
room_formcon_list (nfcl, fcl -> sz);
nfcl -> sz = fcl -> sz;
for (ix = 0; ix < fcl -> sz; ix++)
nfcl -> arr [ix] = add_to_repls_from_fc
(repls, org,
fcl -> arr[ix], fcdefs);
return (new_FCList (nfcl));
};
break;
default: badtag (fc -> tag);
};
};
static void add_to_repls_from_val (repls, org, v, t)
repl_list repls;
orig org;
val v;
typ t;
{ switch (v -> tag)
{ case TAGVSym:
{ val newlocs = unique_val_of_type (org, t);
app_repl_list (repls, new_repl
(rdup_symbol (v -> VSym.sym), newlocs));
};
break;
case TAGVList:
{ val_list vl = v -> VList.l;
typ_list tl = t -> TypProd.ptypes;
register int ix;
for (ix = 0; ix < vl -> sz; ix++)
add_to_repls_from_val (repls, org, vl -> arr[ix],
tl -> arr[ix]);
};
break;
default: badtag (v -> tag);
};
};
static repl_list repls_from_local_defs (dl)
def_list dl;
{ register int ix;
repl_list nrepls = new_repl_list ();
for (ix = 0; ix < dl -> sz; ix++)
{ def d = dl -> arr[ix];
add_to_repls_from_val (nrepls, d -> DefConTr.corig,
d -> DefConTr.lhs,
ctypes [d -> DefConTr.nr - proclowend]);
};
return (nrepls);
};
static val make_names_unique_in_val ();
static def make_names_unique_in_def (repls, d)
repl_list repls;
def d;
{ val nlhs, nrhs;
nlhs = make_names_unique_in_val (repls, d -> DefConTr.lhs);
nrhs = make_names_unique_in_val (repls, d -> DefConTr.rhs);
return (new_DefConTr (rdup_orig (d -> DefConTr.corig),
nlhs, nrhs,
d -> DefConTr.nr));
};
static val make_names_unique_in_val (repls, v)
repl_list repls;
val v;
{ switch (v -> tag)
{ case TAGVSym:
{ register int ix;
for (ix=0; ix < repls -> sz; ix++)
if (v -> VSym.sym == repls -> arr[ix] -> rsym)
return (rdup_val (repls -> arr[ix] -> repval));
return (rdup_val (v));
};
case TAGVList:
{ register int ix;
val_list vl = v -> VList.l;
val_list nvl = new_val_list ();
room_val_list (nvl, vl -> sz);
nvl -> sz = vl -> sz;
for (ix = 0; ix < vl -> sz; ix++)
nvl -> arr [ix] = make_names_unique_in_val
(repls, vl -> arr[ix]);
return (new_VList (nvl));
};
case TAGVAtom:
{ return (new_VAtom (rdup_orig (v -> VAtom.atorig),
rdup_symbol (v -> VAtom.atnm),
rdup_parval_list (v -> VAtom.atvpar),
make_names_unique_in_val
(repls, v -> VAtom.atcpar)));
};
case TAGVWhere:
{ val newwval, retval;
repl_list locreps;
register int ix;
def_list ldefs = v -> VWhere.wdefs;
def_list ndefs = new_def_list ();
room_def_list (ndefs, ldefs -> sz);
ndefs -> sz = ldefs -> sz;
locreps = repls_from_local_defs (ldefs);
conc_repl_list (locreps, rdup_repl_list (repls));
newwval = make_names_unique_in_val
(locreps, v -> VWhere.wval);
for (ix=0; ix < ldefs -> sz; ix++)
ndefs -> arr [ix] = make_names_unique_in_def
(locreps, ldefs -> arr[ix]);
retval = new_VWhere (ndefs, newwval);
rfre_repl_list (locreps);
return (retval);
};
default: badtag (v -> tag);
};
};
static val make_all_names_unique (org)
orig org;
{ val newval;
repl_list first_repls = new_repl_list ();
fcdefs = new_def_list ();
newfc = add_to_repls_from_fc (first_repls, org, deffc, fcdefs);
newval = make_names_unique_in_val (first_repls, defval);
rfre_repl_list (first_repls);
return (newval);
};
/*
Now that symbols are unique merge all local
definitions into one where clause
*/
static val merge_all_wheres_in_val ();
static void merge_all_wheres_in_def (d, ndefs)
def d;
def_list ndefs;
{ val nrhs = merge_all_wheres_in_val (d -> DefConTr.rhs, ndefs);
val nlhs = rdup_val (d -> DefConTr.lhs);
def ndef = new_DefConTr (rdup_orig (d -> DefConTr.corig),
nlhs, nrhs, d -> DefConTr.nr);
app_def_list (ndefs, ndef);
};
static val merge_all_wheres_in_val (v, ndefs)
val v;
def_list ndefs;
{ switch (v -> tag)
{ case TAGVSym:
return (rdup_val (v));
case TAGVList:
{ register int ix;
val_list vl = v -> VList.l;
val_list nvl = new_val_list ();
room_val_list (nvl, vl -> sz);
nvl -> sz = vl -> sz;
for (ix = 0; ix < vl -> sz; ix++)
nvl -> arr[ix] = merge_all_wheres_in_val
(vl -> arr[ix], ndefs);
return (new_VList (nvl));
};
case TAGVAtom:
return (new_VAtom (rdup_orig (v -> VAtom.atorig),
rdup_symbol (v -> VAtom.atnm),
rdup_parval_list (v -> VAtom.atvpar),
merge_all_wheres_in_val
(v -> VAtom.atcpar, ndefs)));
case TAGVWhere:
{ def_list dl = v -> VWhere.wdefs;
register int ix;
for (ix = 0; ix < dl -> sz; ix++)
merge_all_wheres_in_def (dl -> arr [ix], ndefs);
return (merge_all_wheres_in_val (v -> VWhere.wval, ndefs));
};
default: badtag (v -> tag);
};
};
static val merge_all_wheres (org, v, t)
orig org;
val v;
typ t;
{ val nlhs = unique_val_of_type (org, t);
def_list ndefs = new_def_list ();
val nrhs = merge_all_wheres_in_val (v, ndefs);
def ndef = new_DefConTr (rdup_orig (org), rdup_val (nlhs),
nrhs, procnr);
ctypes [procnr - proclowend] = rdup_typ (t);
procnr++;
app_def_list (ndefs, ndef);
return (new_VWhere (ndefs, nlhs));
};
/*
unfold all defs so that atom applications no longer have
atom applications as actual arguments.
*/
static val try_unfold_atoms_in_val (v, ndefs)
val v;
def_list ndefs;
{ switch (v -> tag)
{ case TAGVSym:
return (rdup_val (v));
case TAGVList:
{ register int ix;
val_list vl = v -> VList.l;
val_list nvl = new_val_list ();
room_val_list (nvl, vl -> sz);
nvl -> sz = vl -> sz;
for (ix = 0; ix < vl -> sz; ix++)
nvl -> arr[ix] = try_unfold_atoms_in_val
(vl -> arr[ix], ndefs);
return (new_VList (nvl));
};
case TAGVAtom:
{ val atcarg = v -> VAtom.atcpar;
def d = find_def (v -> VAtom.atnm);
typ atctyp = d -> DefAtom.atctyp -> TypUni.uityp;
val newatc = try_unfold_atoms_in_val (atcarg, ndefs);
val nlhs = unique_val_of_type
(rdup_orig (v -> VAtom.atorig), atctyp);
def newdef = new_DefCon
(rdup_orig (v -> VAtom.atorig), nlhs, newatc);
app_def_list (ndefs, newdef);
return (new_VAtom (rdup_orig (v -> VAtom.atorig),
rdup_symbol (v -> VAtom.atnm),
rdup_parval_list (v -> VAtom.atvpar),
rdup_val (nlhs)));
};
default: badtag (v -> tag);
};
};
static void try_unfold_atoms_in_def (d, ndefs)
def d;
def_list ndefs;
{ val nlhs = rdup_val (d -> DefConTr.lhs);
val nrhs = try_unfold_atoms_in_val (d -> DefConTr.rhs, ndefs);
def ndef = new_DefCon (rdup_orig (d -> DefConTr.corig), nlhs, nrhs);
app_def_list (ndefs, ndef);
};
static val try_unfold_atoms (v)
val v;
{ register int ix;
val trhs = rdup_val (v -> VWhere.wval);
def_list odefs = v -> VWhere.wdefs;
def_list ndefs = new_def_list ();
room_def_list (ndefs, odefs -> sz);
context = new_ctx_list ();
ins_ctx_list (context, 0, new_ctx (rdup_def_list (newdefs)));
for (ix = 0; ix < odefs -> sz; ix++)
try_unfold_atoms_in_def (odefs -> arr[ix], ndefs);
rfre_ctx_list (context);
return (new_VWhere (ndefs, trhs));
};
/*
Try and split all definitions into single wire ones
*/
static void try_form_separate_defs (org, lhs, rhs, ndefs)
orig org;
val lhs, rhs;
def_list ndefs;
{ val_list lvl, rvl;
register int ix;
if ((rhs -> tag == TAGVAtom) ||
(rhs -> tag == TAGVSym) ||
(lhs -> tag == TAGVSym))
{ def nd = new_DefCon (rdup_orig (org), rdup_val (lhs),
rdup_val (rhs));
app_def_list (ndefs, nd);
return;
};
lvl = lhs -> VList.l;
rvl = rhs -> VList.l;
if (lvl -> sz != rvl -> sz) Die ("Incompatible sizes");
for (ix = 0; ix < lvl -> sz; ix++)
try_form_separate_defs (org, lvl -> arr[ix],
rvl -> arr[ix], ndefs);
};
static val try_split_defs (v)
val v;
{ register int ix;
val trhs = rdup_val (v -> VWhere.wval);
def_list odefs = v -> VWhere.wdefs;
def_list ndefs = new_def_list ();
room_def_list (ndefs, odefs -> sz);
for (ix = 0; ix < odefs -> sz; ix++)
{ def d = odefs -> arr[ix];
try_form_separate_defs (d -> DefCon.conorig, d -> DefCon.defcon,
d -> DefCon.conas, ndefs);
};
return (new_VWhere (ndefs, trhs));
};
/*
try and simplify the definitions so that only the external inputs
and outputs and the intermediair contacts appear in the defs.
*/
static int *local_xref, *local_xref_trans;
static val *local_val;
#define no_appear (-2)
#define must_appear (-1)
static mark_symbol (s, org, alt)
symbol s;
orig org;
int alt;
{ int nr = getprior (s);
local_xref [nr] = alt;
if (alt == must_appear) local_xref_trans [nr] = alt;
local_val [nr] = new_VSym (org, s);
};
static void mark_symbols_in_fc (org, fc)
orig org;
formcon fc;
{ switch (fc -> tag)
{ case TAGFCSym:
mark_symbol (fc -> FCSym.sym, org, must_appear);
break;
case TAGFCList:
{ formcon_list fcl = fc -> FCList.l;
register int ix;
for (ix = 0; ix < fcl -> sz; ix++)
mark_symbols_in_fc (org, fcl -> arr[ix]);
};
break;
default: badtag (fc -> tag);
};
};
static void mark_symbols_in_val (v)
val v;
{ switch (v -> tag)
{ case TAGVSym:
mark_symbol (v -> VSym.sym, v -> VSym.symorig, must_appear);
break;
case TAGVList:
{ val_list vl = v -> VList.l;
register int ix;
for (ix = 0; ix < vl -> sz; ix++)
mark_symbols_in_val (vl -> arr[ix]);
};
break;
default: badtag (v -> tag);
};
};
static void try_mark_in_def (d)
def d;
{ val lhs = d -> DefCon.defcon;
val rhs = d -> DefCon.conas;
if (rhs -> tag == TAGVAtom)
{ mark_symbols_in_val (lhs);
}
else if ((lhs -> tag == TAGVSym) &&
(rhs -> tag == TAGVSym))
{ mark_symbol (lhs -> VSym.sym, lhs -> VSym.symorig,
getprior (rhs -> VSym.sym));
}
else Die ("Strange lists found\n");
};
static void init_simp_arrays ()
{ int ix;
local_xref = (int *) ckcalloc (uniquenr, sizeof (int));
local_xref_trans = (int*) ckcalloc (uniquenr, sizeof (int));
local_val = (val *) ckcalloc (uniquenr, sizeof (val));
for (ix = 0; ix < uniquenr; ix++) local_xref [ix] = no_appear;
for (ix = 0; ix < uniquenr; ix++) local_xref_trans [ix] = no_appear;
};
static void do_transitive_closure ()
{ int localnr;
for (localnr = 0; localnr < uniquenr; localnr++)
if (local_xref [localnr] != no_appear)
{ int localnr2 = localnr;
while (local_xref [localnr2] != must_appear)
localnr2 = local_xref [localnr2];
local_xref_trans [localnr] = localnr2;
};
};
static val simplify_val (v)
val v;
{ switch (v -> tag)
{ case TAGVSym:
{ int nr = getprior (v -> VSym.sym);
int nr2 = local_xref_trans [nr];
if (nr2 == must_appear) return (rdup_val (v));
return (rdup_val (local_val [nr2]));
};
case TAGVList:
{ register int ix;
val_list vl = v -> VList.l;
val_list nvl = new_val_list ();
room_val_list (nvl, vl -> sz);
nvl -> sz = vl -> sz;
for (ix = 0; ix < vl -> sz; ix++)
nvl -> arr[ix] = simplify_val (vl -> arr[ix]);
return (new_VList (nvl));
};
case TAGVAtom:
return (new_VAtom (rdup_orig (v -> VAtom.atorig),
rdup_symbol (v -> VAtom.atnm),
rdup_parval_list (v -> VAtom.atvpar),
simplify_val (v -> VAtom.atcpar)));
case TAGVWhere:
default: badtag (v -> tag);
};
};
static void try_add_simplified_def (d, ndefs)
def d;
def_list ndefs;
{ def ndef;
val lhs = d -> DefCon.defcon;
val rhs = d -> DefCon.conas;
if (lhs -> tag == TAGVSym)
{ int nr = getprior (lhs -> VSym.sym);
if (local_xref [nr] != must_appear) return;
};
if (lhs -> tag == TAGVList)
{ val_list vl = lhs -> VList.l;
if (vl -> sz == 0) return;
};
ndef = new_DefCon (rdup_orig (d -> DefCon.conorig),
rdup_val (lhs),
simplify_val (rhs));
app_def_list (ndefs, ndef);
};
static val try_simplify_defs (org, v)
orig org;
val v;
{ register int ix;
val trhs = rdup_val (v -> VWhere.wval);
val nrhs;
def_list odefs = v -> VWhere.wdefs;
def_list ndefs = new_def_list ();
init_simp_arrays ();
mark_symbols_in_fc (org, newfc);
for (ix = 0; ix < odefs -> sz; ix++)
try_mark_in_def (odefs -> arr[ix]);
do_transitive_closure ();
for (ix = 0; ix < odefs -> sz; ix++)
try_add_simplified_def (odefs -> arr[ix], ndefs);
nrhs = simplify_val (trhs);
return (new_VWhere (ndefs, nrhs));
};
/*
prepare and transform the values
*/
static void prepare (dl)
def_list dl;
{ def d, nd;
val lambdaexp, newval, newval2, newval3, newval4, newval5;
orig org;
fprintf (stderr, "uflat2: preparing...\n");
newdefs = new_def_list ();
copy_basenamedefs (newdefs, dl);
d = find_thedef (dl);
org = rdup_orig (d -> DefVal.valorig);
lambdaexp = d -> DefVal.valas;
intyp = rdup_typ (d -> DefVal.valtyp -> TypUni.uityp);
outtyp = rdup_typ (d -> DefVal.valtyp -> TypUni.uotyp);
deffc = rdup_formcon (lambdaexp -> VLambda.lpar);
defval = prepare_val (lambdaexp -> VLambda.lval);
prepare_formcon (deffc, intyp);
prepare_types ();
fprintf (stderr, "uflat2: transforming...\n");
newval = make_all_names_unique (org);
newval2 = merge_all_wheres (org, newval, outtyp);
newval3 = try_unfold_atoms (newval2);
newval4 = try_split_defs (newval3);
newval5 = try_simplify_defs (org, newval4);
if (orignames)
{ nd = new_DefVal (org, rdup_symbol (d -> DefVal.valnm),
rdup_typ (d -> DefVal. valtyp),
new_VLambda (rdup_formcon (deffc),
new_VWhere (rdup_def_list (fcdefs),
newval5)));
}
else
{ nd = new_DefVal (org, rdup_symbol (d -> DefVal.valnm),
rdup_typ (d -> DefVal. valtyp),
new_VLambda (rdup_formcon (newfc), newval5));
};
app_def_list (newdefs, nd);
rfre_val (newval);
rfre_val (newval2);
rfre_val (newval3);
rfre_val (newval4);
};
/*
Load all the definitions
*/
static void load (f, dl)
FILE *f;
def_list *dl;
{ if (fscan_def_list (f, dl))
{ fprintf (stderr, "Read error: (%d): %s\n", tmlineno, tmerrmsg);
exit (1);
};
};
main (argc, argv)
int argc;
char *argv [];
{ def_list all_defs;
initsymbol ();
scanargs (argc, argv);
tmlineno = 1;
load (infile, &all_defs);
prepare (all_defs);
fprint_def_list (outfile, newdefs);
if (stat)
{ int ix;
rfre_def_list (all_defs);
rfre_formcon (deffc);
rfre_val (defval);
rfre_typ (intyp);
rfre_typ (outtyp);
for (ix=0; ix < procnr - proclowend; ix++)
rfre_typ (ctypes[ix]);
flushsymbol ();
stat_ds (stderr);
stat_string (stderr);
};
}